﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.DirectX.Direct3D;

using DataObjects;
using DataObjects.Enums;
using DataObjects.Interfaces;
using DataObjects.Behaviours;
using DataObjects.ShipSystems;

using GraphicalObjects;

namespace GameRules
{
    static public class GameFactory
    {
        static private List<ISystem> availableSystems = new List<ISystem>();
        static private Dictionary<string, ObjectMesh> meshList = new Dictionary<string, ObjectMesh>();

        static public GameObject BuildGamePiece(int team)
        {
            return new GameObject(team);
        }

        static public void BuildGraphicalObject(GameObject obj, ref Device device)
        {
            if (!meshList.ContainsKey("Ship_06.x"))
                meshList.Add("Ship_06.x", new ObjectMesh("Ship_06.x", ref device));
            //ObjectMesh shipMesh = new ObjectMesh("tiger.x", ref device);

            Ship ship = new Ship(meshList["Ship_06.x"], obj);
            GameScene.Add(ship);
        }

        static public GameObject BuildGamePiece(BahaviourTypes behaviour, int team)
        {
            GameObject obj = BuildGamePiece(team);
            AddBehaviour(behaviour, obj);
            obj.AddWeaponSystem(GameFactory.RetrieveSystem("Gun") as IWeapon, 1);

            return obj;
        }

        static public GameObject BuildStarbase(BahaviourTypes behaviour, int team)
        {
            GameObject obj = new Starbase(team);
            AddBehaviour(behaviour, obj);
            obj.AddWeaponSystem(GameFactory.RetrieveSystem("Gun") as IWeapon, 1);
            obj.AddWeaponSystem(GameFactory.RetrieveSystem("Gun") as IWeapon, 1);

            return obj;
        }
        
        static public void AddBehaviour(BahaviourTypes behaviour, GameObject piece)
        {
            BaseBehaviour beh = null;

            switch (behaviour)
            {
                case BahaviourTypes.Aggresive:
                    beh = new AggresiveBehaviour(piece);
                    break;
                case BahaviourTypes.Defensive:
                    beh = new DefensiveBehaviour(piece);
                    break;
                default:
                case BahaviourTypes.Normal:
                    beh = new NormalBehaviour(piece);
                    break;
            }

            piece.Behaviour = beh;
        }

        static public void InitialiseSystems()
        {
            ISystem wp1 = new Weapon { Name = "Gun", PowerCost = 10f, BaseCooldown = 2000, WeaponSize = 1, BaseDamage = 2f, 
                                       SystemType = ShipSystemType.WEAPON_SYSTEM, WeaponType = WeaponType.DIRECT_FIRE };

            availableSystems.Add(wp1);
        }

        static public ISystem RetrieveSystem(string name)
        {
            ISystem sys = availableSystems.FirstOrDefault(s => s.Name.Equals(name));
            if (sys == null)
                throw new Exception("Unable to find system.");

            return sys.Clone() as ISystem;
        }
    }
}
